#include "stdafx.h"
#include "VertexStream.h"

namespace WindGE
{
	VertexStream::VertexStream()
		: name_("")
		, buffer_(nullptr)
		, stride_(0)
		, count_(0)
		, offset_(0)
	{
	}

	VertexStream::VertexStream(const VertexStream& vertexStream)
	{
		name_ = vertexStream.name_;
		stride_ = vertexStream.stride_;
		count_ = vertexStream.count_;
		offset_ = vertexStream.offset_;
		
		safe_delete(buffer_);
		buffer_ = malloc(stride_*count_);
		memcpy(buffer_, vertexStream.buffer_, stride_*count_);
	}

	VertexStream::~VertexStream()
	{
		safe_delete(buffer_);
	}

	bool VertexStream::init(const std::string& name, unsigned int stride, unsigned int count)
	{
		name_ = name;
		stride_ = stride;
		count_ = count;
		offset_ = 0;

		buffer_ = malloc(stride_*count_);

		return (buffer_ != nullptr);
	}

	bool VertexStream::reinit(unsigned int num)
	{
		count_ += num;

		buffer_ = realloc(buffer_, count_*stride_);

		return (buffer_ != nullptr);
	}

	bool VertexStream::load(std::istream& inFile)
	{
		//read name size
		unsigned int nameSize = 0;
		inFile.read((char*)&nameSize, sizeof(nameSize));
		//read name
		char* name = new char[nameSize];
		inFile.read(name, nameSize);
		name_ = name;
		safe_delete_array(name);

		//read stride
		inFile.read((char*)&stride_, sizeof(stride_));

		//read count
		inFile.read((char*)&count_, sizeof(count_));

		//read offset
		inFile.read((char*)&offset_, sizeof(offset_));

		//read type
		unsigned int type = 0;
		inFile.read((char*)&type, sizeof(type));
		type_ = (EVertexStreamType)type;

		//read buffer
		safe_delete(buffer_);
		buffer_ = malloc(stride_*count_);
		inFile.read((char*)buffer_, stride_*offset_);

		return true;
	}

	bool VertexStream::save(std::ostream& outFile)
	{
		//write name
		unsigned int nameSize = name_.size();
		outFile.write((char*)&nameSize, sizeof(nameSize));
		outFile.write(name_.c_str(), nameSize);

		//write stride
		outFile.write((char*)&stride_, sizeof(stride_));

		//write count
		outFile.write((char*)&count_, sizeof(count_));

		//write offset
		outFile.write((char*)&offset_, sizeof(offset_));

		//write type
		outFile.write((char*)((unsigned int)type_), sizeof((unsigned int)type_));

		//write buffer
		outFile.write((char*)buffer_, offset_*stride_);

		return true;
	}

	void VertexStream::add(void* vertBuff)
	{
		if (offset_+1 >= count_)
		{
			count_ ++;
			buffer_ = realloc(buffer_, count_*stride_);
		}
		memcpy((void*)((char*)buffer_ + offset_*stride_), vertBuff, stride_);
		offset_++;
	}

	void VertexStream::add(void* vertBuff, unsigned int num)
	{
		if (offset_ + num >= count_)
		{
			count_ += num;
			buffer_ = realloc(buffer_, count_*stride_);
		}
		memcpy((void*)((char*)buffer_ + offset_*stride_), vertBuff, stride_*num);
		offset_ += num;
	}

	void VertexStream::set(void* vertBuff, unsigned int offset)
	{
		assert(offset+1 < count_);
		memcpy((void*)((char*)buffer_ + offset*stride_), vertBuff, stride_);
	}

	void VertexStream::set(void* vertBuff, unsigned int offset, unsigned int num)
	{
		assert(offset + num < count_);
		memcpy((void*)((char*)buffer_ + offset*stride_), vertBuff, num*stride_);
	}

}//end namespace WindGE

